package com.wksc.framework.impexp.task;

import com.wksc.framework.impexp.constants.IEConstants;
import com.wksc.framework.impexp.constants.PostfixType;
import com.wksc.framework.impexp.constants.TaskStat;
import com.wksc.framework.impexp.handler.exp.BaseExpHandler;
import com.wksc.framework.impexp.handler.exp.ExpTxtHandler;
import com.wksc.framework.impexp.mode.Mode;
import com.wksc.framework.impexp.mode.ModeFactory;
import com.wksc.framework.impexp.result.ExpResult;
import com.wksc.framework.impexp.template.ExpTemplate;
import com.wksc.framework.impexp.util.ClassFactory;
import com.wksc.framework.impexp.util.ImpExpTools;

import java.io.File;
import java.io.FileNotFoundException;
import java.sql.SQLException;
import java.util.List;
import java.util.zip.ZipFile;

/**
 * <p>
 * Title(文件名): ExpTask.java
 * </p>
 * <p>
 * Description(描述): 导出任务的处理类
 * </p>
 * <p>
 * Copyright(版权): Copyright (c) 2011
 * </p>
 * <p>
 * Company(公司): 成都四方信息技术有限公司
 * </p>
 * <p>
 * CreateTime(生成日期)：2011-10-20下午03:40:30
 * </p>
 * 
 * @author wanglei
 * @version impExp_C13
 */
public class ExpTask extends Task {

	private static final long serialVersionUID = 8458599463185061895L;

	private BaseExpHandler expHandler;

	/**
	 * 继承的构造函数
	 * 
	 * @param expTemplate
	 *            导出模板
	 * @throws ClassNotFoundException
	 *             初始化时设置任务类型时为找到对应Class异常
	 */
	public ExpTask(ExpTemplate expTemplate) throws ClassNotFoundException {
		super(expTemplate);
		//初始化结果导出任务对象
		this.result = new ExpResult();
	}

	/**
	 * 导出操作的具体业务处理过程
	 * 
	 * @throws InterruptedException
	 *             中断异常
	 * @throws java.sql.SQLException
	 *             数据库异常
	 * @throws Exception
	 *             其他异常
	 */
	@Override
	protected void process() throws InterruptedException, SQLException,
			FileNotFoundException, Exception {
		//每页数据,数据对象类型为List<Object[]>
		List<?> data = null;
		//单次成功写入文件的条数
		int succNum = 0;

		/* ============ 初始化导入的Modehandler start ================ */
		ExpTemplate expTemplate = (ExpTemplate) baseTemplate;
		Mode expMode = expTemplate.getExpFileMode();
		expHandler = ModeFactory.getExpModeHandler(expMode, expTemplate);
		/* ============ 初始化导入的Modehandler end ================= */

		//从数据库获取待导出数据的总条数,若总条数等于零则直接结束导出任务
		int totalLoopTime = expHandler.getLoopTime();
		expHandler = expHandler.getHandlerInstance();

		result.setPostfix(expHandler.getPostfix());
		if (0 == totalLoopTime) {
			//总页数为0
			result.setResultMsg(ClassFactory.getI18n().getNoDataInfo());
			return;
		}

		try {
			/* 分loopTime次生成导出文件 */
			for (int i = 1; i <= totalLoopTime; i++) {
				//1.查库前检查中断情况
				if (checkInterrupted()) {
					return;
				}
				//2.获取单次处理数据
				data = expHandler.getDividedData(i);
				if (null == data) {
					continue;
				}
				//3.格式化前检查中断情况
				if (checkInterrupted()) {
					return;
				}
				//4.格式化数据
				data = expHandler.formatData(data);
				//5.写文件前再次判断中断情况
				if (checkInterrupted()) {
					return;
				}
				//6.写入文件
				succNum = expHandler.writeToFile(data);
				result.setTotalNum(result.getTotalNum() + succNum);
			} //end for loop
		} catch (Exception e) {
			log.error(e.getMessage(), e); //如果tem没有权限,这里抛出空指针
		} finally {
			//导出文件管理
			if (expHandler instanceof ExpTxtHandler) {
				ExpTxtHandler.number = 0;
			}
			fileManage(expHandler.isMultiFile());
		}
	}//end process()

	/**
	 * 方法描述：导出完成后对文件进行管理
	 * 
	 * @creator wanglei
	 * @param multiFiles
	 */
	private void fileManage(boolean multiFiles) {
		String goalSrc = IEConstants.EXP_PATH; // 复制到的路径
		if (!multiFiles) { //导出单个文件
			StringBuffer fileSrc = new StringBuffer().append(
					IEConstants.TEM_PATH).append(IEConstants.SEPARATOR).append(
					baseTemplate.getFileName()).append(
					result.getPostfix().toString()); // 导出文件的路径
			File zipFile = new File(fileSrc.toString());
			if (!zipFile.canRead()) {
				throw new RuntimeException(zipFile.getAbsolutePath()
						+ "(Access denied!)");
			}
			//FileTools.isFolderExists(goalSrc, true);
			if (!ImpExpTools.dirHavePriv(goalSrc, false, true, false)) {
				throw new RuntimeException(goalSrc + "(Access denied!)");
			}
			//FileTools.moveFile(fileSrc.toString(), goalSrc);
			result.setAllCorrect(IEConstants.HAS_EXPORT_FILE);
		} else { //导出多个文件
			StringBuffer fileSrc = new StringBuffer().append(
					IEConstants.TEM_PATH).append(IEConstants.SEPARATOR).append(
					baseTemplate.getFileName());
			File srcFile = new File(fileSrc.toString());
			File temFile = new File(IEConstants.TEM_PATH);
			if (!ImpExpTools.dirHavePriv(temFile.getAbsolutePath(), true, true, false)) {
				throw new RuntimeException(temFile.getAbsolutePath()
						+ "(Access denied!)");
			}
			if (!srcFile.canRead()) {
				throw new RuntimeException(srcFile.getAbsolutePath()
						+ "(Access denied!)");
			}
			//待打包的目录不为目录或为空文件夹则直接返回
			if (!srcFile.isDirectory() || srcFile.list().length == 0) {
				return;
			}
			//ZipFile.fileZip(fileSrc.toString() + ".zip", fileSrc.toString());
			// 压缩到本文件夹
			File zipFile = new File(fileSrc.toString() + ".zip");
			if (!zipFile.canRead()) {
				throw new RuntimeException(zipFile.getAbsolutePath()
						+ "(Access denied!)");
			}
			if (!ImpExpTools.dirHavePriv(goalSrc, false, true, false)) {
				throw new RuntimeException(goalSrc + "(Access denied!)");
			}
			//FileTools.moveFile(fileSrc.toString() + ".zip", goalSrc);
			// 删除文件夹
			//FileTools.delFileFolder(fileSrc.toString());
			result.setAllCorrect(IEConstants.HAS_EXPORT_FILE);
			result.setPostfix(PostfixType.ZIP);
		}
	}

	@Override
	protected void beforeExit() {
	}

	@Override
	public void cancelTask() {
		ClassFactory.getImpExpDao().updateTaskCurrentState(this,
				TaskStat.TASK_CANCELLED);
		this.cancelTask = true;
	}
}//end this class
